﻿#include "convertthread.h"
#include <QDebug>
#include <QException>
#include <QFile>
#include <QMessageBox>
#include <QTextStream>
#include <QDataStream>
#include <QVector>

#include <memory>

void CSV2BINThread::run() {
  try {
    std::unique_ptr<QFile> write_file_(new QFile(save_file_path));
    if (!write_file_->open(QIODevice::WriteOnly)) {
      throw std::runtime_error("Error: Unable to open the output file for writing.");
    }

    std::unique_ptr<QFile> inFile(new QFile(read_file_path));
    if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
      throw std::runtime_error("Error: opening file fail");
    }

    QTextStream inStream(inFile.get());
    QDataStream outStream(write_file_.get());

    // Skip header line
    inStream.readLine();

    QVector<QVector<double>> data(CHANNELS);

    int ans = 0;
    // Process each line of the CSV
    while (!inStream.atEnd()) {
      QString line = inStream.readLine();
      QStringList fields = line.trimmed().split(",");

      // fields个数相当于通道数
      for (int t = 0; t < fields.size(); ++t) {
        // 跳过空值
        if (fields.at(t).isEmpty()) {
          continue;
        }

        if (arr_enableChannel_[t]) {
          bool ok;
          double value = fields.at(t).toDouble(&ok);
          if (ok) {
            data[t].append(value);
          } else {
            qWarning() << "Error converting field to double at line" << ans + 1;
          }
        }
      }

      ++ans;
      // Write data when sample_rate is reached
      if (ans >= sample_rate) {
        for (int i = 0; i < CHANNELS; ++i) {
          outStream << data[i];
          data[i].clear();
        }
        ans = 0;
      }
    }

    inFile->close();
    write_file_->flush();
    write_file_->close();
  }catch (const QException& e){
    qWarning() << "An exception occurred: " << e.what();
  }catch (const std::exception &e) {
    qWarning() << "An exception occurred: " << e.what();
  } catch (...){
    qWarning() << "An exception occurred.";
  }

  qDebug() << "CSV2BINThread finished.";
  emit QuitThread(); // Ensure the signal name matches the declaration in the header file.
}


void BIN2CSVThread::run() {
  try {
    std::unique_ptr<QFile> read_file(new QFile(read_file_path));
    if (!read_file->open(QIODevice::ReadOnly)) {
      throw std::runtime_error("Error: Unable to open the input file for reading.");
    }

    std::unique_ptr<QFile> out_file(new QFile(save_file_path));
    if (!out_file->open(QIODevice::WriteOnly | QIODevice::Text)) {
      throw std::runtime_error("Error: unable to open the output file for writing.");
    }

    QTextStream outStream(out_file.get());
    // Write CSV header
    for (int i = 0; i < CHANNELS; i++) {
      if (arr_enableChannel_[i]) {
        QString str(u8"通道" + QString::number(i).toUtf8() + u8",");
        outStream << str;
      }
    }
    outStream << Qt::endl;

    QVector<QVector<double>> data(CHANNELS);
    QDataStream inStream(read_file.get());
    inStream.device()->seek(0);

    while (!inStream.atEnd()) {
      std::vector<double> buffer(sample_rate); // 动态创建vector缓冲区

      for (int var = 0; var < CHANNELS; ++var) {
        if (arr_enableChannel_[var]) {
          inStream.readRawData(reinterpret_cast<char *>(buffer.data()), sample_rate * sizeof(double));
          data[var].resize(sample_rate);
          std::copy(buffer.begin(), buffer.end(), data[var].begin());
        }
      }

      // Write data from binary file to CSV
      for (int x = 0; x < sample_rate; ++x) {
        for (int i = 0; i < CHANNELS; i++) {
          if (arr_enableChannel_[i]) {
            outStream << data[i][x] << ',';
          }
        }
        outStream << Qt::endl;
      }
    }
  } catch (const std::exception &e) {
    qCritical() << "An exception occurred: " << e.what();
    return;
  }

  qDebug() << "BIN2CSVThread finished.";
  emit QuitThread(); // Ensure the signal name matches the declaration in the header file.
}

